#region imports
using System;
using System.Collections;
using System.IO;
using System.Net.Mail;
using System.Web;
using System.Web.UI;
using PHSRAG.Insight21.CDS;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.FormsManagement;
using PHSRAG.Insight21.Humans;
using PHSRAG.Utility;
using Constants = PHSRAG.Insight21.FormsManagement.Constants;
#endregion

namespace PHSRAG.Insight21.Research
{
    public partial class TrainingAnswerQuestionnaire : CachePage
    {
        #region Constants
            private const string AnnunciatorTitle = "The following error(s) occurred...";
            private const string ProtocolAccessLevelKey = "ProtocolAccessLevel_732B4039-15AA-4083-83AB-413FCA803A76";
            private const string QuestionnaireAnswerIdKey = "QAId_732B4039-15AA-4083-83AB-413FCA803A76";
            private const string QuestionnaireVersionIdKey = "QVId_732B4039-15AA-4083-83AB-413FCA803A76";
        #endregion

        #region InstanceVars
            private Person currentUser;
            private QuestionnaireAnswer questionnaireAnswerForm;
            private string questionnaireAnswerFormName;
            private string questionnaireName;
            private QuestionnaireVersion questionnaireVersion;
            private string species;
            private UserContext userContext;
            private Protocol protocol;
            private ProtocolProcess protocolProcess;
        #endregion

        #region Constructors
        public TrainingAnswerQuestionnaire()
            : base("TrainingAnswerQuestionnairePage_732B4039-15AA-4083-83AB-413FCA803A76"){}
        #endregion

        #region Page Event Handlers
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {                
                userContext = PrevailingCachePolicy.GetCachedObject(UserContext.CacheKey) as UserContext;
             
                currentUser = new Person(PrevailingCachePolicy);
                currentUser.Load(DataAccess.GetConnectionString(), userContext.PersonId);

                string occHealthDownload = Request.QueryString["DownloadOccHealth"];
                protocol = PrevailingCachePolicy.GetCachedObject(Protocol.ProtocolKey) as Protocol;
                protocolProcess = PrevailingCachePolicy.GetCachedObject(ProtocolProcess.ProtocolProcessKey) as ProtocolProcess;
                speciesCode.Text = protocol.SpeciesMeaning.ToString();
                speciesCode.Attributes["style"] = "display:none";

                if (protocol == null)
                {
                    throw new Exception("TrainingAnswerQuestionaire: Protocol cannot be null");
                }
                if (!string.IsNullOrEmpty(occHealthDownload))
                {
                    DownloadOccHealth(protocol.Id, currentUser.Id);
                    return;
                }

                questionnaireName = Request.QueryString["Type"];
                if (string.IsNullOrEmpty(questionnaireName))
                {
                    throw new Exception("TrainingAnswerQuestionaire: Page is being viewed out of context. ");
                }

                species = protocol.SpeciesMeaning;

                questionnaireAnswerFormName = (questionnaireName == Constants.AnimalsQuestionnaireCommonFormNames.OccHealth) ? questionnaireName : string.Format("{0} {1}", species, questionnaireName);

                if (!IsPostBack && postbackGuard.IsValid)
                {
                    questionnaireVersion = Questionnaire.GetActiveVersion(PrevailingCachePolicy, questionnaireName, Constants.QuestionnaireType.Animals);
                    questionnaireVersion.Cache();

                    questionnaireAnswerForm = currentUser.GetCertificationQuestionnaireAnswer(DataAccess.GetConnectionString(), questionnaireAnswerFormName);
                    if (questionnaireAnswerForm == null)
                    {
                        questionnaireAnswerForm = new QuestionnaireAnswer(PrevailingCachePolicy);
                        questionnaireAnswerForm.Name = questionnaireAnswerFormName;
                        questionnaireAnswerForm.QuestionnaireVersionId = questionnaireVersion.Id;
                        questionnaireAnswerForm.LastModifiedByAdmPersonId = currentUser.Id;
                    }
                    questionnaireAnswerForm.Cache();
                    questionnaireViewer.LoadQuestionnaire(questionnaireVersion, questionnaireAnswerForm);

                    questionaireTitle.Text = questionnaireVersion.Questionnaire.Name;
                }
                else
                {
                    questionnaireVersion = new QuestionnaireVersion(PrevailingCachePolicy);
                    questionnaireVersion = PrevailingCachePolicy.GetCachedObject(questionnaireVersion.CacheKey()) as QuestionnaireVersion;

                    questionnaireAnswerForm = new QuestionnaireAnswer(PrevailingCachePolicy);
                    questionnaireAnswerForm = PrevailingCachePolicy.GetCachedObject(questionnaireAnswerForm.CacheKey()) as QuestionnaireAnswer;
                }
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(annunciator, ex, true);
                imgBtnSave.Enabled = false;
            }
        }
        #endregion

        #region Control Event Handlers
        /// <summary>
        /// Saves all the answers entered by the user.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnImgBtnSaveClick(object sender, ImageClickEventArgs e)
        {
            try
            {                
               string errorMessage = String.Empty;

               if (!questionnaireViewer.SaveQuestionnaire(questionnaireAnswerForm))
               {
                    return;
               }

               //Occ Health form
               if (questionnaireName == Constants.AnimalsQuestionnaireCommonFormNames.OccHealth) 
                {                    
                    //no errors found save returns bool on validation.
                    if (questionnaireViewer.ValidateRequiredQuestions(errorMessage))
                    {
                        try
                        {
                            currentUser.SaveCertification(DataAccess.GetConnectionString(), DataAccess.GetConnectionString("Rex"),
                            questionnaireAnswerForm, "IACUC Continuing Education", "Occupational health program", "Required Training", "Pass", string.Empty);

                            // close the popup window
                            Page.ClientScript.RegisterClientScriptBlock(GetType(), "OccHealth", "<script language='javascript'>window.close();</script>");
                        
                        }
                        catch
                        {
                            SendOccHealthMail();
                        }
                    }                   
                }
                else //Experience form
                {                   
                    string notes = string.Empty;
                    //gets notes for experience or noexperience from the text box.
                    ArrayList answers = questionnaireAnswerForm.GetAnswers("Experience");
                    if (answers.Count > 0)
                    {
                        notes = ((Answer)(((Answer)answers[0]).ChildAnswers[0])).Value;
                    }
                    else
                    {
                        answers = questionnaireAnswerForm.GetAnswers("NoExperience");
                        if (answers.Count > 0)
                        {
                            notes = ((Answer)(((Answer)answers[0]).ChildAnswers[0])).Value;
                        }
                    }

                    try
                    {
                        //make sure the value for Species never changes, tried to disable the textbox,
                        //but than it will not be generated and saved to DB.
                        for (int i = 0; i < questionnaireAnswerForm.Answers.Count; ++i)
                        {
                            if (((Answer)(questionnaireAnswerForm.Answers[i])).Name == "Species")
                                ((Answer)(questionnaireAnswerForm.Answers[i])).Value = speciesCode.Text;
                        }
                        
                        //check for errors.
                        if (questionnaireViewer.ValidateRequiredQuestions(errorMessage))
                        {
                            currentUser.SaveCertification(DataAccess.GetConnectionString(), DataAccess.GetConnectionString("Rex"),
                                questionnaireAnswerForm, "IACUC", questionnaireAnswerFormName, "Required Training", "Pass", notes);

                            // close the popup window if validation succeed.
                            Page.ClientScript.RegisterClientScriptBlock(GetType(), "OccHealth", "<script language='javascript'>window.close();</script>");
                        }                       
                    }
                    catch
                    {             
                        //if any erro is found certification email is sent to dmm25.
                        SendSaveCertificationFailedEmail(((Answer)answers[0]).QuestionnaireAnswerId);
                    }                   
                }
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(annunciator, ex, true);
                imgBtnSave.Enabled = false;
            }
        }
        #endregion

        #region Private Methods
        /// <summary>
        /// Sends an email to Occ Health with the current users Occ Health Survey form as an attachment
        /// </summary>
        private void SendSaveCertificationFailedEmail(int questionnaireId)
        {
            try
            {
                EMailTemplate emailTemplate = new EMailTemplate(PrevailingCachePolicy);
                emailTemplate.Load(DataAccess.ConnectionString, "ANIMALS_SAVECERTFAILEDEMAIL", BusinessObjects.ModuleKey.Animals);
                MailMessage message = new MailMessage(emailTemplate.From, emailTemplate.To,
                    emailTemplate.Subject,
                    string.Format(emailTemplate.BodyText, protocol.ProtocolNumber, protocol.Title, protocol.PIName, (protocolProcess == null) ? string.Empty : protocolProcess.Name, currentUser.Username));
                message.IsBodyHtml = true;

                if (protocol == null)
                {
                    throw new Exception("Email cannot be sent: Protocol cannot be null");
                }
                string outputFile = string.Empty;                
                    outputFile = GenerateCertificationDocument(protocol.Id, currentUser.Id);
               

                Attachment attachment = new Attachment(new MemoryStream(GetBytesFromFile(outputFile)), "QualificationsAndExperience.pdf");
                message.Attachments.Add(attachment);

                SmtpClient client = new SmtpClient(Settings.GetKeyValue("Email.SMTPServer", "127.0.0.1"));
                client.UseDefaultCredentials = true;
                client.Send(message);
            }
            catch (Exception ex)
            {
                ExceptionReport.WriteToEventLog(String.Format("Failed to send a failed email for QualificationsAndExperience"),
                    ex, true, ExceptionReport.ReportType.Error);
            }
        }

        /// <summary>
        /// Sends an email to Occ Health with the current users Occ Health Survey form as an attachment
        /// </summary>
        private void SendOccHealthMail()
        {
            MailMessage message = new MailMessage();
            message.From = new MailAddress(userContext.EmailAddress);
            message.To.Add(Settings.GetKeyValue("Email.Animal.OccHealth.ToEmail", string.Empty));
            message.Subject = Settings.GetKeyValue("Email.Animal.OccHealth.Subject", string.Empty);
            message.Body = Settings.GetKeyValue("Email.Animal.OccHealth.Body", string.Empty);
            message.IsBodyHtml = true;

            Protocol protocol = PrevailingCachePolicy.GetCachedObject(Protocol.ProtocolKey) as Protocol;
            if (protocol == null)
            {
                throw new Exception("Email cannot be sent: Protocol cannot be null");
            }

            string outputFile = GenerateCertificationDocument(protocol.Id, currentUser.Id);

            Attachment attachment = new Attachment(new MemoryStream(GetBytesFromFile(outputFile)), "OccHealthSurveyForm.pdf");
            message.Attachments.Add(attachment);

            SmtpClient client = new SmtpClient(Settings.GetKeyValue("Email.SMTPServer", "127.0.0.1"));
            client.UseDefaultCredentials = true;
            client.Send(message);
        }

        ///// <summary>
        ///// Generate a pdf file as a Document object for the form
        ///// </summary>
        ///// <param name="protocolId">protocol Id</param>
        ///// <param name="personId ">personId Id</param>
        ///// <returns></returns>
        private string GenerateCertificationDocument(int protocolId, int personId)
        {
            InsightServiceUtility.DocumentUtility docUtility = new InsightServiceUtility.DocumentUtility();
            ArrayList answers = questionnaireAnswerForm.GetAnswers("Qualifications");
            return docUtility.GetStaffCertificateForSpecie(protocolId, personId, UIUtility.GetFullDocStagingFolderPath(),
                protocol.SpeciesMeaning);
           
        }

        /// <summary>
        /// Generate & download OccHealth Form
        /// </summary>
        /// <param name="protocolId"></param>
        /// <param name="personId"></param>
        private void DownloadOccHealth(int protocolId, int personId)
        {
            questionnaireName = Constants.AnimalsQuestionnaireCommonFormNames.OccHealth;
            string outputFile = GenerateCertificationDocument(protocolId, personId);

            if (outputFile == null)
            {
                throw new Exception("Training-Answer-Questionnaire: Error generating pdf: Output file is empty");
            }

            Response.Clear();
            Response.ClearHeaders();
            Response.AppendHeader("content-disposition", "attachment; filename=Application.pdf");
            Response.ContentType = "Application/pdf";
            try
            {
                Response.TransmitFile(outputFile); //transmitFilePath);
                Response.End();
            }
            catch (Exception ex)
            {
                ExceptionReport.WriteToEventLog(String.Format("Failed while transmitting the file {0} to the client.", outputFile),
                    ex, true, ExceptionReport.ReportType.Error);
            }
        }

        /// <summary>
        /// Read the files as byte array
        /// </summary>
        /// <param name="fullFilePath">Full Path of the file to be read</param>
        /// <returns>byte array of the file content</returns>
        public static byte[] GetBytesFromFile(string fullFilePath)
        {
            // this method is limited to 2^32 byte files (4.2 GB)
            byte[] bytes = null;
            try
            {
                using (FileStream fs = new FileStream(fullFilePath, FileMode.Open, FileAccess.Read))
                {
                    bytes = new byte[fs.Length];
                    fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
                    fs.Close();
                }
            }
            catch (Exception ex)
            {
                ExceptionReport.WriteToEventLog("GetBytesFromFile ():\r Error: ", ex.Message, ExceptionReport.ReportType.Error);
            }
            return bytes;
        }
        #endregion
    }
}